<?php

namespace Tools\Root\HttpClient;

/**
 * Class BaseClient
 *
 * @package Tools\Root\HttpClient
 */
class BaseClient implements Client
{
    /**
     * Permissions persist the storage file.
     *
     * @var string
     */
    protected string $loadFile = '';

    /**
     * Server config
     *
     * @var array
     */
    protected array $serviceConfig = [];

    /**
     * Base url
     *
     * @var string
     */
    protected string $baseUrl = '';

    /**
     * @var bool
     */
    protected bool $isInitialize = false;

    /**
     * Permission information.
     *
     * @var Authority
     */
    protected Authority $loader;

    /**
     * Https client
     *
     * @var \GuzzleHttp\Client
     */
    protected \GuzzleHttp\Client $client;

    /**
     * HanZiClient constructor.
     *
     * @param string $loadFile
     * @param array $serviceConfig
     */
    public function __construct(string $loadFile, array $serviceConfig)
    {
        $this->loadFile = $loadFile;
        $this->serviceConfig = $serviceConfig;
    }

    /**
     * Initialize
     *
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Exception
     */
    public function initialize()
    {
        // storage data
        $this->loader = new Authority($this->loadFile);
        $this->loader->initialize();

        // client request url
        $this->baseUrl = "{$this->serviceConfig['schema']}://{$this->serviceConfig['host']}:{$this->serviceConfig['port']}";

        // proxy client
        $this->client = new \GuzzleHttp\Client([
            'base_uri' => $this->baseUrl,
        ]);

        $this->isInitialize = true;
    }

    /**
     * Close client.
     *
     * @throws \Exception
     */
    public function close()
    {
        if (!$this->isInitialize) {
            $this->loader->persistent(true);

            $this->isInitialize = false;
        }
    }

    /**
     * Service status.
     *
     * @return bool
     */
    public function status() : bool
    {
        return $this->isInitialize;
    }

    /**
     * Send request
     *
     * @param string $method
     * @param string $uri
     * @param array $options
     * @return \stdClass
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function request(string $method, $uri = '', array $options = []) : \stdClass
    {
        // override headers
        foreach ($this->serviceConfig['headers'] as $key => $value) {
            $options['headers'][$key] = $value;
        }

        $response = $this->client->request($method, $uri, $options);

        $content = $response->getBody()->getContents();
        if ($content !== '') {
            $data = json_decode($content, false,512, JSON_UNESCAPED_UNICODE);

            return $data;
        }

        throw new \Exception('Request Exception!');
    }
}
